import {
  Injectable,
  NotFoundException,
  ForbiddenException,
  BadRequestException,
  ConflictException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In } from 'typeorm';
import { Work, WorkStatusEnum, MediaTypeEnum } from './entities/work.entity';
import { Like } from './entities/like.entity';
import { Collection } from './entities/collection.entity';
import { User } from '../auth/entities/user.entity';
import { CreateWorkDto } from './dto/create-work.dto';
import { UpdateWorkDto } from './dto/update-work.dto';

@Injectable()
export class WorksService {
  constructor(
    @InjectRepository(Work)
    private readonly workRepository: Repository<Work>,
    @InjectRepository(Like)
    private readonly likeRepository: Repository<Like>,
    @InjectRepository(Collection)
    private readonly collectionRepository: Repository<Collection>,
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) { }

  /**
   * 创建作品
   */
  async create(createWorkDto: CreateWorkDto, userId: number): Promise<Work> {
    // 验证媒体类型与媒体内容匹配
    if (
      createWorkDto.mediaType === MediaTypeEnum.IMAGE &&
      (!createWorkDto.imagesUrls || createWorkDto.imagesUrls.length === 0)
    ) {
      throw new BadRequestException('图片类型作品必须包含至少一张图片');
    }
    if (
      createWorkDto.mediaType === MediaTypeEnum.VIDEO &&
      !createWorkDto.videoUrl
    ) {
      throw new BadRequestException('视频类型作品必须包含视频URL');
    }

    const workData = {
      ...createWorkDto,
      authorId: userId,
      status: createWorkDto.status || WorkStatusEnum.DRAFT,
      publishedAt:
        createWorkDto.status === WorkStatusEnum.PUBLISHED ? new Date() : null,
    };
    //TODO:图片和视频的url需要存储到数据库中,源文件存储到本地

    const savedWork = await this.workRepository.save(workData);

    // 如果是发布状态，更新用户的作品计数
    if (savedWork.status === WorkStatusEnum.PUBLISHED) {
      await this.incrementUserWorksCount(userId);
    }

    return savedWork;
  }

  /**
   * 获取作品列表（分页）
   */
  async findAll(
    page: number = 1,
    limit: number = 10,
    category?: string,
    status?: WorkStatusEnum,
    keyword?: string,
  ) {
    const query = this.workRepository
      .createQueryBuilder('work')
      .leftJoinAndSelect('work.author', 'author')
      .select(['work', 'author.id', 'author.username', 'author.avatar']);

    // 只返回公开的已发布作品（除非指定了状态）
    if (!status) {
      query.where('work.status = :status', {
        status: WorkStatusEnum.PUBLISHED,
      });
      query.andWhere('work.isPublic = :isPublic', { isPublic: true });
    } else {
      query.where('work.status = :status', { status });
    }

    // 按类别筛选
    if (category) {
      query.andWhere('work.category = :category', { category });
    }

    // 搜索关键词（搜索标题、描述、标签）
    if (keyword && keyword.trim()) {
      const searchKeyword = `%${keyword.trim()}%`;
      // 搜索标题、描述，以及标签（通过 JSON 字符串匹配）
      // 注意：对于标签搜索，我们使用 JSON 字符串包含的方式
      query.andWhere(
        '(work.title LIKE :keyword OR work.description LIKE :keyword OR CAST(work.tags AS CHAR) LIKE :tagKeyword)',
        {
          keyword: searchKeyword,
          tagKeyword: searchKeyword,
        },
      );
    }

    // 按发布时间倒序排列
    query.orderBy('work.publishedAt', 'DESC');

    // 分页
    query.skip((page - 1) * limit).take(limit);

    const [works, total] = await query.getManyAndCount();

    return {
      data: works,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  /**
   * 获取用户的作品列表
   */
  async findByUser(
    userId: number,
    currentUserId?: number,
    page: number = 1,
    limit: number = 10,
    status?: WorkStatusEnum,
  ) {
    const query = this.workRepository
      .createQueryBuilder('work')
      .leftJoinAndSelect('work.author', 'author')
      .select(['work', 'author.id', 'author.username', 'author.avatar'])
      .where('work.authorId = :userId', { userId });

    // 如果指定了状态，按状态筛选
    if (status) {
      query.andWhere('work.status = :status', { status });
    } else {
      // 如果不是作者本人，只返回公开的已发布作品
      if (!currentUserId || currentUserId !== userId) {
        query.andWhere('work.status = :status', {
          status: WorkStatusEnum.PUBLISHED,
        });
        query.andWhere('work.isPublic = :isPublic', { isPublic: true });
      }
    }

    query
      .orderBy('work.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);

    const [works, total] = await query.getManyAndCount();

    return {
      data: works,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  /**
   * 获取作品详情
   */
  async findOne(
    id: number,
    userId?: number,
  ): Promise<Work & { isLiked?: boolean; isCollected?: boolean }> {
    const work = await this.workRepository.findOne({
      where: { id },
      relations: ['author'],
    });

    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 如果作品未公开或为草稿，只有作者可以查看
    if (
      (!work.isPublic || work.status !== WorkStatusEnum.PUBLISHED) &&
      work.authorId !== userId
    ) {
      throw new ForbiddenException('无权访问此作品');
    }

    // 增加浏览量（可以添加去重逻辑，避免同一用户多次浏览重复计数）
    await this.workRepository.increment({ id }, 'viewsCount', 1);

    // 如果提供了用户ID，查询用户是否已点赞和收藏
    let isLiked = false;
    let isCollected = false;

    if (userId) {
      // 查询点赞状态
      const likeRecord = await this.likeRepository.findOne({
        where: {
          workId: id,
          userId: userId
        },
      });
      isLiked = !!likeRecord;

      // 查询收藏状态
      const collectionRecord = await this.collectionRepository.findOne({
        where: {
          workId: id,
          userId: userId
        },
      });
      isCollected = !!collectionRecord;

      // 调试日志
      console.log(`[findOne] workId: ${id}, userId: ${userId}, isLiked: ${isLiked}, isCollected: ${isCollected}`);
      if (likeRecord) {
        console.log(`[findOne] Like record found:`, likeRecord);
      }
      if (collectionRecord) {
        console.log(`[findOne] Collection record found:`, collectionRecord);
      }
    } else {
      console.log(`[findOne] No userId provided, workId: ${id}`);
    }

    // 返回作品信息及用户状态
    return {
      ...work,
      isLiked,
      isCollected,
    };
  }

  /**
   * 更新作品
   */
  async update(
    id: number,
    updateWorkDto: UpdateWorkDto,
    userId: number,
  ): Promise<Work> {
    const work = await this.workRepository.findOne({ where: { id } });

    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 只有作者可以修改
    if (work.authorId !== userId) {
      throw new ForbiddenException('无权修改此作品');
    }

    // 如果状态从草稿改为发布，设置发布时间并更新用户作品计数
    const wasPublished = work.status === WorkStatusEnum.PUBLISHED;
    const willBePublished = updateWorkDto.status === WorkStatusEnum.PUBLISHED;

    if (!wasPublished && willBePublished) {
      updateWorkDto['publishedAt'] = new Date();
      await this.incrementUserWorksCount(userId);
    } else if (
      wasPublished &&
      updateWorkDto.status &&
      updateWorkDto.status !== WorkStatusEnum.PUBLISHED
    ) {
      // 如果从发布改为草稿或归档，减少用户作品计数
      await this.decrementUserWorksCount(userId);
    }

    Object.assign(work, updateWorkDto);
    return await this.workRepository.save(work);
  }

  /**
   * 删除作品
   */
  async remove(id: number, userId: number): Promise<void> {
    const work = await this.workRepository.findOne({ where: { id } });

    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 只有作者可以删除
    if (work.authorId !== userId) {
      throw new ForbiddenException('无权删除此作品');
    }

    // 如果是已发布的作品，减少用户作品计数
    if (work.status === WorkStatusEnum.PUBLISHED) {
      await this.decrementUserWorksCount(userId);
    }

    await this.workRepository.remove(work);
  }

  /**
   * 发布作品（从草稿到发布）
   */
  async publish(id: number, userId: number): Promise<Work> {
    return this.update(id, { status: WorkStatusEnum.PUBLISHED }, userId);
  }

  /**
   * 保存为草稿
   */
  async saveToDraft(id: number, userId: number): Promise<Work> {
    return this.update(id, { status: WorkStatusEnum.DRAFT }, userId);
  }

  /**
   * 切换点赞状态（自动判断点赞/取消）
   */
  async toggleLike(
    workId: number,
    userId: number,
  ): Promise<{
    action: 'liked' | 'unliked';
    message: string;
    isLiked: boolean;
  }> {
    // 查询点赞记录
    const likeRecord = await this.likeRepository.findOne({
      where: { workId, userId },
    });

    if (likeRecord) {
      // 已点赞，取消点赞
      await this.unlike(workId, userId);
      return { action: 'unliked', message: '取消点赞成功', isLiked: false };
    } else {
      // 未点赞，添加点赞
      await this.like(workId, userId);
      return { action: 'liked', message: '点赞成功', isLiked: true };
    }
  }

  /**
   * 点赞作品
   */
  async like(workId: number, userId: number): Promise<void> {
    const work = await this.workRepository.findOne({ where: { id: workId } });
    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 检查是否已点赞
    const existingLike = await this.likeRepository.findOne({
      where: { workId, userId },
    });
    if (existingLike) {
      throw new ConflictException('已经点赞过该作品');
    }

    // 创建点赞记录
    const like = this.likeRepository.create({ workId, userId });
    await this.likeRepository.save(like);

    // 增加作品点赞数
    await this.workRepository.increment({ id: workId }, 'likesCount', 1);

    // 增加作者获赞数
    await this.userRepository.increment(
      { id: work.authorId },
      'receivedLikesCount',
      1,
    );

    // 增加用户点赞数
    await this.userRepository.increment({ id: userId }, 'likesCount', 1);
  }

  /**
   * 取消点赞
   */
  async unlike(workId: number, userId: number): Promise<void> {
    const work = await this.workRepository.findOne({ where: { id: workId } });
    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 查找点赞记录
    const likeRecord = await this.likeRepository.findOne({
      where: { workId, userId },
    });
    if (!likeRecord) {
      throw new NotFoundException('未找到点赞记录');
    }

    // 删除点赞记录
    await this.likeRepository.remove(likeRecord);

    // 减少作品点赞数
    await this.workRepository.decrement({ id: workId }, 'likesCount', 1);

    // 减少作者获赞数
    await this.userRepository.decrement(
      { id: work.authorId },
      'receivedLikesCount',
      1,
    );

    // 减少用户点赞数
    await this.userRepository.decrement({ id: userId }, 'likesCount', 1);
  }

  /**
   * 切换收藏状态（自动判断收藏/取消）
   */
  async toggleCollect(
    workId: number,
    userId: number,
  ): Promise<{
    action: 'collected' | 'uncollected';
    message: string;
    isCollected: boolean;
  }> {
    // 查询收藏记录
    const collectionRecord = await this.collectionRepository.findOne({
      where: { workId, userId },
    });

    if (collectionRecord) {
      // 已收藏，取消收藏
      await this.uncollect(workId, userId);
      return {
        action: 'uncollected',
        message: '取消收藏成功',
        isCollected: false,
      };
    } else {
      // 未收藏，添加收藏
      await this.collect(workId, userId);
      return { action: 'collected', message: '收藏成功', isCollected: true };
    }
  }

  /**
   * 收藏作品
   */
  async collect(workId: number, userId: number): Promise<void> {
    const work = await this.workRepository.findOne({ where: { id: workId } });
    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 检查是否已收藏
    const existingCollection = await this.collectionRepository.findOne({
      where: { workId, userId },
    });
    if (existingCollection) {
      throw new ConflictException('已经收藏过该作品');
    }

    // 创建收藏记录
    const collection = this.collectionRepository.create({ workId, userId });
    await this.collectionRepository.save(collection);

    // 增加作品收藏数
    await this.workRepository.increment({ id: workId }, 'collectionsCount', 1);

    // 增加用户收藏数
    await this.userRepository.increment({ id: userId }, 'collectionsCount', 1);
  }

  /**
   * 取消收藏
   */
  async uncollect(workId: number, userId: number): Promise<void> {
    const work = await this.workRepository.findOne({ where: { id: workId } });
    if (!work) {
      throw new NotFoundException('作品不存在');
    }

    // 查找收藏记录
    const collectionRecord = await this.collectionRepository.findOne({
      where: { workId, userId },
    });
    if (!collectionRecord) {
      throw new NotFoundException('未找到收藏记录');
    }

    // 删除收藏记录
    await this.collectionRepository.remove(collectionRecord);

    // 减少作品收藏数
    await this.workRepository.decrement({ id: workId }, 'collectionsCount', 1);

    // 减少用户收藏数
    await this.userRepository.decrement({ id: userId }, 'collectionsCount', 1);
  }

  /**
   * 增加用户作品计数
   */
  private async incrementUserWorksCount(userId: number): Promise<void> {
    await this.userRepository.increment({ id: userId }, 'worksCount', 1);
  }

  /**
   * 减少用户作品计数
   */
  private async decrementUserWorksCount(userId: number): Promise<void> {
    await this.userRepository.decrement({ id: userId }, 'worksCount', 1);
  }

  /**
   * 获取当前用户的收藏列表
   */
  async findMyCollections(
    userId: number,
    page: number = 1,
    limit: number = 10,
  ) {
    // 先查询收藏记录，获取作品ID和收藏时间
    const collections = await this.collectionRepository.find({
      where: { userId },
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
    });

    const workIds = collections.map((c) => c.workId);

    if (workIds.length === 0) {
      return {
        data: [],
        total: 0,
        page,
        limit,
        totalPages: 0,
      };
    }

    // 查询作品详情
    const works = await this.workRepository.find({
      where: {
        id: In(workIds),
        status: WorkStatusEnum.PUBLISHED,
      },
      relations: ['author'],
    });

    // 按照收藏时间排序
    const workMap = new Map(works.map((w) => [w.id, w]));
    const sortedWorks = collections
      .map((c) => workMap.get(c.workId))
      .filter((w) => w !== undefined) as Work[];

    // 获取总数
    const total = await this.collectionRepository.count({
      where: { userId },
    });

    return {
      data: sortedWorks,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }
}
